<template>
  <div class="image-downloader">
    <input
      v-model="imageUrl"
      type="text"
      placeholder="输入图片URL"
      class="url-input"
    />
    <button @click="downloadImage" class="download-btn">
      下载图片为Base64
    </button>

    <div v-if="base64Image" class="result-area">
      <h3>预览：</h3>
      <img :src="base64Image" alt="下载的图片" class="preview-img" />
      <textarea
        v-model="base64Image"
        class="base64-text"
        rows="5"
        placeholder="base64编码将显示在这里"
      ></textarea>
    </div>

    <div v-if="errorMessage" class="error-message">
      {{ errorMessage }}
    </div>
  </div>
</template>

<script setup>
import { ref } from "vue";
import axios from "axios";

// 响应式变量
const imageUrl = ref("https://picsum.photos/800/600"); // 默认示例图片
const base64Image = ref("");
const errorMessage = ref("");

// 下载图片并转换为base64
const downloadImage = async () => {
  // 清空之前的结果和错误信息
  base64Image.value = "";
  errorMessage.value = "";

  try {
    // 验证URL
    if (!isValidUrl(imageUrl.value)) {
      errorMessage.value = "请输入有效的图片URL";
      return;
    }

    // 发起请求，获取二进制数据
    const response = await axios.get(imageUrl.value, {
      responseType: "arraybuffer", // 关键：获取二进制数据
      headers: {
        "User-Agent":
          "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
      },
    });

    // 获取图片MIME类型
    const contentType = response.headers["content-type"] || "image/jpeg";

    // 转换二进制数据为base64（浏览器环境使用btoa）
    const base64String = btoa(
      new Uint8Array(response.data).reduce(
        (data, byte) => data + String.fromCharCode(byte),
        ""
      )
    );

    // 拼接完整的base64格式
    base64Image.value = `data:${contentType};base64,${base64String}`;
  } catch (error) {
    console.error("图片下载失败:", error);
    errorMessage.value = `下载失败: ${error.message || "未知错误"}`;
  }
};

// URL验证函数
const isValidUrl = (url) => {
  try {
    new URL(url);
    return true;
  } catch (e) {
    return false;
  }
};
</script>

<style scoped>
.image-downloader {
  max-width: 800px;
  margin: 20px auto;
  padding: 20px;
}

.url-input {
  width: 100%;
  padding: 8px 12px;
  margin-bottom: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.download-btn {
  background-color: #42b983;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  margin-bottom: 20px;
}

.download-btn:hover {
  background-color: #359e75;
}

.result-area {
  margin-top: 20px;
}

.preview-img {
  max-width: 100%;
  border-radius: 4px;
  margin-bottom: 10px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.base64-text {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-family: monospace;
  font-size: 12px;
  resize: vertical;
}

.error-message {
  color: #ff4444;
  margin-top: 10px;
  padding: 8px;
  background-color: #ffebee;
  border-radius: 4px;
}
</style>
